/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jobscheduling.model;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import jobscheduling.algorithms.ResultListener;

/**
 *
 * @author Dawid
 */
public class Solution implements ResultListener, Serializable{
    protected List<int[]> _permutations = new LinkedList<int[]>();
    protected List<Integer>   _times = new LinkedList<Integer>();
    protected String _algorithm;
    protected Map<String, String> _params;
    protected Integer _bestScore;
    protected Problem _problem;
    protected Problem _bestPerm;
    protected Computation _computation;
    protected Integer _bestIteration;
    protected Integer _currentIteration;
    protected Integer _bestTime;
    
    public Solution(String algorithm, Map<String, String> params, Problem problem, Computation computation){
        _algorithm = algorithm;
        _params = params;
        _problem = problem;
        _computation = computation;
        _bestIteration = 0;
        _currentIteration = 0;
    }
    
    @Override
    public synchronized void newResult(int[] permutation, int totalTime) {
        _currentIteration += 1;
        if(_bestIteration == 0 || totalTime < _bestTime){
            _bestIteration = _currentIteration;
            _bestTime = totalTime;
        }
        
        _permutations.add(permutation);
        _times.add(totalTime);
        _bestScore = totalTime;
        _computation.update (_algorithm, permutation, totalTime);
    }
    
    public Integer getBestIteration(){
        return _bestIteration;
    }
    
    public Problem getBestPerm(){
        _bestPerm = new Problem();
        
        Job[] jobs = _problem.getJobs();
        Job[] permJobs = new Job[jobs.length];
        int[] bestPerm = _permutations.get(_permutations.size() - 1);
        for (int i = 0; i < bestPerm.length; ++i){
            permJobs[i] = jobs[bestPerm[i]];
        }
        _bestPerm.setMachinesNumber(_problem.getMachinesNumber());
        _bestPerm.setJobs(permJobs);
        _bestPerm.setName(_problem.getName());
        return _bestPerm;
    }
    
    public Map<String, String> getParameters(){
        return _params;
    }
    
    public int[] getBestPermutation(){
        return _permutations.get(_permutations.size()-1);
    }
    
    public List<int[]> getPermutations (){
        return _permutations;
    }
    
    public List<Integer> getTimes(){
        return _times;
    }
    
    public Problem getProblem(){
        return _problem;
    }
    
    public String getComputingStatus(){
        return _algorithm + 
               "\tIterations: " + Integer.toString(_permutations.size()) + 
               "\tBest score: " + _bestScore;
    }
    
    @Override
    public String toString(){
        return _algorithm + ", total time " + _bestScore;
    }

    void clearComputation() {
        this._computation = null;
    }
}
